﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfFootball.Parser;
using System.Windows.Media.Animation;
using System.Windows.Forms;
#endregion

namespace WpfFootball.UI
{
    /// <summary>
    /// Interaction logic for FourmEntryViewer.xaml
    /// </summary>
    public partial class FourmEntryViewer : UpdatableView
    {
        #region Fields
        private List<ForumEntry> forumEntries;
        #endregion

        public FourmEntryViewer(string teamName)
            : base()
        {
            this.teamName = teamName;
            InitializeView();
            RegisterEventHandlers();
        }

        /// <summary>
        /// Initializes the components of this view.
        /// </summary>
        public override void InitializeView()
        {
            initializing = true;
            viewKind = ViewKind.FORUM;
            parser = new DataParser();
            ioManager = IOManager.Instance();
            InitializeComponent();
            ApplyViewSettings();
            BeginUpdate();
            ScaleUpViewAnimation();
            defaultViewHeight = this.Height;
            initializing = false;
        }

        /// <summary>
        /// Registers additional event handlers to this view.
        /// </summary>
        public override void RegisterEventHandlers()
        {
            base.RegisterEventHandlers();
            parser.ParseForumEntriesCompleted += ForumEntriesParsed;
        }

        #region View Settings
        /// <summary>
        /// Revalidates the menu items of the context menu to match
        /// the settings of this view.
        /// </summary>
        public override void RevalidateContextMenu()
        {
            autoUpdateMenuItem.IsChecked = viewSettings.AutoUpdate;

            switch (viewSettings.UpdateFrequency)
            {
                case 2:
                    updtf2.IsChecked = true;
                    break;
                case 5:
                    updtf5.IsChecked = true;
                    break;
                case 10:
                    updtf10.IsChecked = true;
                    break;
                case 30:
                    updtf30.IsChecked = true;
                    break;
            }

            switch (viewSettings.EntryCounter)
            {
                case 2:
                    entr2.IsChecked = true;
                    break;
                case 4:
                    entr4.IsChecked = true;
                    break;
                case 6:
                    entr6.IsChecked = true;
                    break;
                case 8:
                    entr8.IsChecked = true;
                    break;
                case 10:
                    entr10.IsChecked = true;
                    break;
            }
        }

        /// <summary>
        /// Loads and applies the settings of this view.
        /// </summary>
        public override void ApplyViewSettings()
        {
            viewSettings = ioManager.GetViewSettings(teamName, viewKind);
            SetViewLocation();
            RevalidateContextMenu();
            RevalidateAutoUpdateThread();
        }
        #endregion

        #region Auto Update Thread Handling
        /// <summary>
        /// Auto updates this view with a frequency that depends of the settings of this view. 
        /// This method is and should only be called from another thread to prevent
        /// blocking the UI thread.
        /// </summary>
        public override void AutoUpdateThreadWorker()
        {
            while (true)
            {
                lock (viewSettings)
                {
                    Thread.Sleep(viewSettings.UpdateFrequency * 1000);
                }
                Console.WriteLine("ForumEntry " + teamName + " Updating every: " + viewSettings.UpdateFrequency);
                BeginUpdate();
            }
        }

        /// <summary>
        /// Checks the latest auto update setting status and based of that
        /// aborts or initializes the auto update thread.
        /// </summary>
        public override void RevalidateAutoUpdateThread()
        {
            if (viewSettings.AutoUpdate)
            {
                InitAutoUpdateThread();
            }
            else
            {
                AbortAutoUpdateThread();
            }
        }
        #endregion

        #region Update
        /// <summary>
        /// Atempts to update the view asynchronously.
        /// </summary>
        public void BeginUpdate()
        {
            this.Dispatcher.BeginInvoke(
                new Action(() =>
            {
                RotateControl(0, 360, updateViewButton);
                parser.BeginParseForumEntries(teamName, viewSettings.EntryCounter);
            }));
        }

        /// <summary>
        /// Creates the header of a Expander that consist of the date and sender of the 
        /// current forum entry.
        /// </summary>
        /// <param name="forumEntry">The object that conatains the data to build the header.</param>
        /// <returns>A Stackpanee containing the components of the Expander header.</returns>
        private StackPanel CreateForumEntryHeader(ForumEntry forumEntry)
        {
            StackPanel headerPanel = new StackPanel();

            TextBlock dateTextBlock = new TextBlock();
            dateTextBlock.Style = (Style)this.FindResource("dateTextBlockStyle");
            dateTextBlock.Inlines.Add(new Bold(new Run("Datum: ")));
            dateTextBlock.Inlines.Add(new Run(forumEntry.TimeStamp));

            TextBlock senderTextBlock = new TextBlock();
            senderTextBlock.Style = (Style)this.FindResource("senderTextBlockStyle");
            senderTextBlock.Inlines.Add(new Bold(new Run("Från: ")));
            senderTextBlock.Inlines.Add(new Run(forumEntry.Sender));

            headerPanel.Children.Add(dateTextBlock);
            headerPanel.Children.Add(senderTextBlock);

            return headerPanel;
        }

        /// <summary>
        /// Updates the news of the current team. This method is usually called when 
        /// the ParseForumEntriesCompleted event has been fired.
        /// </summary>
        public void Update()
        {
            stackPanel1.Children.Clear();

            foreach (ForumEntry forumEntry in forumEntries)
            {
                if (forumEntry != null && !string.IsNullOrEmpty(forumEntry.EntryContent))
                {
                    Expander forumEntryExpander = new Expander();
                    forumEntryExpander.Style = (Style)this.FindResource("expanderStyle");
                    forumEntryExpander.Header = CreateForumEntryHeader(forumEntry);

                    StackPanel expanderContent = new StackPanel();
                    expanderContent.Style = (Style)this.FindResource("expanderContentStyle");

                    Border entryBorder = new Border();
                    entryBorder.Style = (Style)this.FindResource("forumEntryBorderStyle");

                    TextBlock forumEntryContent = new TextBlock();
                    forumEntryContent.Style = (Style)this.FindResource("forumEntryContentStyle");
                    forumEntryContent.Text = forumEntry.EntryContent;
                    forumEntryContent.PreviewMouseLeftButtonDown += forumEntryContent_Click;

                    System.Windows.Controls.ToolTip toolTip = new System.Windows.Controls.ToolTip();
                    toolTip.Content = "Klicka för att kopiera innehåll.";
                    forumEntryContent.ToolTip = toolTip;

                    entryBorder.Child = forumEntryContent;
                    expanderContent.Children.Add(entryBorder);
                    forumEntryExpander.Content = expanderContent;
                    stackPanel1.Children.Add(forumEntryExpander);
                }
            }
        }
        #endregion

        #region View Event Handlers
        /// <summary>
        /// Copies the content of a forum entry every time the user hits the corresponding
        /// TextBlock of that entry.
        /// </summary>
        public void forumEntryContent_Click(object sender, System.Windows.Input.MouseEventArgs args)
        {
            System.Windows.Clipboard.SetData(System.Windows.DataFormats.Text, ((TextBlock)sender).Text);
        }

        /// <summary>
        /// Handles the ParseForumEntriesCompleted event.
        /// </summary>
        public void ForumEntriesParsed(object sender, ForumEntriesEventArgs args)
        {
            forumEntries = args.forumEntries;
            StopControlRotation(updateViewButton);
            Update();
        }

        /// <summary>
        /// Attempts to update this view every time the user hits the update button.
        /// </summary>
        private void updateViewButton_Click(object sender, RoutedEventArgs e)
        {
            BeginUpdate();
        }

        /// <summary>
        /// Shows the settings menu of this view.
        /// </summary>
        private void settingsButton_Click(object sender, RoutedEventArgs e)
        {
            settingsMenu.PlacementTarget = this;
            settingsMenu.IsOpen = true;
        }
        #endregion
    }
}
